package com.example.lib_base.base

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.*
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.example.lib_base.utils.MDUtil.getWidthAndHeight

//其实对热门dialog熟悉的话直接调用他们的就行 不用自己封装
abstract class BaseDBDialogFragment : AppCompatDialogFragment() {
    val TAG = "BaseDBDialogFragment"

    private var mActivity: AppCompatActivity? = null
    private var mFragmentProvider: ViewModelProvider? = null
    private var mApplicationProvider: ViewModelProvider? = null
    private var mBinding: ViewDataBinding? = null
    private var dialogHeight: Float = 0f
    private val dialogData = MutableLiveData<Any?>()
    private var dataListener: ((Any?) -> Unit)? = null
    private var isBottom:Boolean = false

    /*
    * 不要在这做视图操作
    * */
    protected fun initViewModel() {}

    //配置DataBinding
    protected abstract fun getDataBindingConfig(): DataBindingConfig?
    /*
    *
    * 生命周期 onViewCreated
    * */
    protected abstract fun initViewOrObserve()

    /*
    * 设置是否设置默认背景透明没有状态栏 默认为true
    * 并设置dialog的高度比
    * 第三个参数针对在dialog后又加一个dialog的背景闪一下的问题，默认false，true就不闪
    * */
    protected fun setTransAndHeight(flag: Boolean = true, dialogHeight: Float = 0.75f,noFlash:Boolean = false) {
        if (flag) {
            dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            //还要加上这个才能没有深色的背景色
            dialog?.window?.setDimAmount(0f)
        }
        if (noFlash){
            dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
        }
        this.dialogHeight = dialogHeight
    }

    fun setBottom(isBoolean: Boolean){
        this.isBottom = isBoolean
    }

    //传入需要的数据 发送数据 目的是等渲染完成在把数据填充？
    fun updateData(data: Any?) {
        dialogData.postValue(data)
    }

    //数据监听
    fun setOnDataListener(listener: (Any?) -> Unit) {
        this.dataListener = listener
    }

    protected fun getFragment(): Fragment {
        return this
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        mActivity = context as AppCompatActivity
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setTransAndHeight(true,0.75f)
        initViewModel()
    }

    protected fun getBinding(): ViewDataBinding? {
        return mBinding
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val dataBindingConfig = getDataBindingConfig()
//        Log.e(TAG, "onCreateView: $inflater")
        //TODO tip: DataBinding 严格模式：
        // 将 DataBinding 实例限制于 base 页面中，默认不向子类暴露，
        // 通过这样的方式，来彻底解决 视图调用的一致性问题，
        // 如此，视图调用的安全性将和基于函数式编程思想的 Jetpack Compose 持平。
        val binding = DataBindingUtil.inflate<ViewDataBinding>(
            inflater,
            dataBindingConfig!!.layout,
            container,
            false
        )
        binding.lifecycleOwner = viewLifecycleOwner
        if (dataBindingConfig.stateViewModel != null) binding.setVariable(
            dataBindingConfig.vmVariableId,
            dataBindingConfig.stateViewModel
        )
        val bindingParams = dataBindingConfig.bindingParams
        var i = 0
        val length = bindingParams.size()
        while (i < length) {
            binding.setVariable(bindingParams.keyAt(i), bindingParams.valueAt(i))
            i++
        }
        mBinding = binding

        if (dialog != null) {
            //点击弹窗外面不消失 返回键消失 默认
//            dialog!!.setCanceledOnTouchOutside(false)
            //点击返回键也没有 为避免某些特殊问题设置只能点按钮
            dialog!!.setCancelable(false)
        }
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //数据观察 并提交数据
        dialogData.observe(viewLifecycleOwner) { dataListener?.invoke(it) }
        if (isBottom){
            dialog?.window?.attributes?.let {
                it.gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
                //动画
//                it.windowAnimations =
            }
        }
        if (mBinding != null) {
            initViewOrObserve()
        }
    }

    protected fun <T : ViewModel> getFragmentScopeViewModel(modelClass: Class<T>): T{
        if (mFragmentProvider == null) {
            mFragmentProvider = ViewModelProvider(this)
        }
        return mFragmentProvider!![modelClass]
    }


    protected fun <T : ViewModel> getApplicationScopeViewModel(modelClass: Class<T>): T {
        if (mApplicationProvider == null) {
            mApplicationProvider =
                ViewModelProvider((mActivity?.applicationContext as BaseApplication))
        }
        return mApplicationProvider!![modelClass]
    }

    protected fun getApplicationContext(): Context? {
        return mActivity!!.applicationContext
    }

    //固定0.75 可自己设置占比
    override fun onResume() {
        super.onResume()
        //单位px
        val window = dialog?.window?.windowManager?.getWidthAndHeight() //获取到屏幕的宽高
        if (window != null) {
            if (window.first > window.second){
                window.first.let {
                    dialog?.window?.setLayout(
                        (it * dialogHeight).toInt(),
                        ViewGroup.LayoutParams.MATCH_PARENT
                    )
                }
            }else{
                window.second.let {
                    dialog?.window?.setLayout(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        (it * dialogHeight).toInt()
                    )
                }
            }
        }
    }


    override fun onDestroyView() {
        super.onDestroyView()
        mBinding?.unbind()
        mBinding = null
    }



}